package com.yc.http.v1.impl;

import com.yc.http.v1.Cookie;
import com.yc.http.v1.HttpServletRequest;
import com.yc.http.v1.HttpSession;
import org.apache.ibatis.annotations.Param;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class HttpServletRequestImpl implements HttpServletRequest {

    private String method;
    private String requestURI;
    private String protocol;
    private Map<String,String> headerMap = new HashMap<>();
    private Map<String,String> paramterMap = new HashMap<>();

    @Override
    public String toString() {
        return "HttpServletRequestImpl{" +
                "method='" + method + '\'' +
                ", requestURI='" + requestURI + '\'' +
                ", protocol='" + protocol + '\'' +
                ", headerMap=" + headerMap +
                '}';
    }

    // 一次读取一个字符, 读完一行返回
    public String readLine(InputStream in) throws IOException {
        StringBuilder line = new StringBuilder();
        while(true){
            char c= (char) in.read();
            if(c=='\r'){
                // 读 \n
                in.read();
                break;
            }
            line.append(c);
        }
        return line.toString();
    }

    public HttpServletRequestImpl(Socket socket) throws IOException {
        final InputStream in = socket.getInputStream();
//        InputStreamReader isr = new InputStreamReader(in);
//        BufferedReader br = new BufferedReader(isr);
        String line;
        int i = 0;
        while( ( line = readLine(in) ) != null ){
            System.out.println(line);
            if(i==0){
                final String[] strings = line.split(" ");
                method = strings[0];
                requestURI = strings[1];
                protocol = strings[2];
            } else if(line.isEmpty()){
                // 读到空行, 头域数据读取结束
                break;
            } else {
                final String[] strings = line.split(": ");
                headerMap.put(strings[0],strings[1]);
            }
            i++;
        }

        // 后是body的内容
        StringBuilder body = new StringBuilder();
        String s = headerMap.get("Content-Length");
        if(s!=null){
            final int contentLength = Integer.parseInt(s);
            for (int j = 0; j < contentLength; j++) {
                char c = (char) in.read();
                body.append(c);
            }
        }
//        byte[] bytes = new byte[1024];
//        int count;
//        while((count = in.read(bytes))>-1){
//            body.append(new String(bytes,0,count));
//        }

        // 请求参数: 1.URI中, 2.body
        final int index = requestURI.indexOf("?");
        if(index > -1){
            String paramstr = requestURI.substring( index + 1 );
            parseParameter(paramstr);
        }

        // body 中的参数如何处理?
        if(body.length()>0){
            System.out.println("body = " + body);
            if("application/x-www-form-urlencoded"
                    .equals(this.getHeader("Content-Type"))){
                parseParameter(body.toString());
            } else if ("application/json"
                    .equals(this.getHeader("Content-Type"))){
                // TODO new Gson => map
            } else if ("multipart/form-data"
                    .equals(this.getHeader("Content-Type"))){
                // TODO 文件上传
            }
        }

        System.out.println(this);

    }

    private void parseParameter(String paramstr){
        // ?a=1&b=2&c=3...
        final String[] split = paramstr.split("&");
        for (String s : split) {
            final String[] split1 = s.split("=");
            if(split1.length==1){
                // 空字符串参数
                paramterMap.put(split1[0],"");
            } else {
                // a=b
                paramterMap.put(split1[0],split1[1]);
            }
        }
    }

    @Override
    public InputStream getInputStream() {
        return null;
    }

    @Override
    public String getMethod() {
        return method;
    }

    @Override
    public String getRequestURI() {
        return requestURI;
    }

    @Override
    public String getProtocol() {
        return protocol;
    }

    @Override
    public String getHeader(String name) {
        return headerMap.get(name);
    }

    @Override
    public Cookie[] getCookies() {
        final String cookieStr = this.getHeader("Cookie");
        if(cookieStr==null)return null;
        final String[] split1 = cookieStr.split(";\\s*");
        Cookie[] cookies = new Cookie[split1.length];
        for (int i = 0; i < split1.length; i++) {
            final String[] split2 = split1[i].split("=");
            cookies[i] = new CookieImpl(split2[0], split2[1]);
        }
        return cookies;
    }

    @Override
    public String getRequestedSessionId() {
        return null;
    }

    @Override
    public HttpSession getSession() {
        // 获取会话ID(cookie)
        String id = null;
        final Cookie[] cookies = getCookies();
        if(cookies!=null){
            for (Cookie cookie : cookies) {
                if("JSESSIONID".equals(cookie.getName())){
                    id = cookie.getValue();
                    break;
                }
            }
        }
        //  id => 空 => 第一次访问
        //  id => 非空 => 第N次访问
        //          => 找不到会话对象 => 会话超时
        //          => 找到了

        // 从会话容器中获取会话对象
        if( id != null && TomcatImpl.sessionMap.containsKey(id)){
            // 有 => return
            HttpSessionImpl session = (HttpSessionImpl) TomcatImpl.sessionMap.get(id);
            // 更新最后访问时间
            session.lastAccesssedTime = System.currentTimeMillis();
            return session;
        }
        // 无 => 创建  => 存入会话容器
        HttpSession session = new HttpSessionImpl();
        TomcatImpl.sessionMap.put(session.getId(), session);
        return session;
    }

    @Override
    public String getParameter(String name) {
        return paramterMap.get(name);
    }

    /**
     * <form action="http://127.0.0.1/mylike.s" method="post">
     *     爱好:<input name="like" type="checkbox">篮球
     *         <input name="like" type="checkbox">唱歌
     *         <input name="like" type="checkbox">跳舞
     *         <input name="like" type="checkbox">电影
     *     <button>提交</button>
     * </form>
     * 扩展: 请求实现获取数组型参数方法, 并定义Serlvet输出选择的爱好
     */
    @Override
    public String[] getParameterValues(String name) {
        return new String[0];
    }

    @Override
    public String getQueryString() {
        return null;
    }

    @Override
    public void getSession(HttpSession session) {

    }
}
